package datetime

import (
	"ZHONGYIHANGYAN/util/log"
	"time"
)

var logErr, logInfo = log.GetLogger("datetime")

const (
	LAYOUT_DATE        string = "2006-01-02"
	LAYOUT_DATE_SIMPLE string = "1-2"
	LAYOUT_TIME_SIMPLE string = "15:04"
	LAYOUT_DATE_TIME   string = "2006-01-02 15:04:05"
)

// DatestrToTimestamp 日期字符串转时间戳
func DatestrToTimestamp(dateStr string) int64 {
	if date, err := time.Parse(LAYOUT_DATE, dateStr); err != nil {
		logErr.Println(err)
		now := time.Now()
		today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
		return today.Unix()
	} else {
		return date.Unix() - 28800 //时区问题，需要减8小时
	}
}

// DatetimestrToTimestamp 时间字符串转时间戳
func DatetimestrToTimestamp(datetimeStr string) int64 {
	time, timeType := TimestrToDatetime(datetimeStr)
	if timeType == "RFC3339" {
		return time.Unix()
	} else {
		return time.Unix() - 28800 //时区问题，需要减8小时
	}
}

// DatetimeToTimestr time.Time转时间字符串
func DatetimeToTimestr(datetime time.Time) string {
	return datetime.Format(LAYOUT_DATE_TIME)
}

// TimestrToDatetime 时间字符串转time.Time
func TimestrToDatetime(timestr string) (time.Time, string) {
	// 尝试使用 RFC3339 格式解析时间
	timeType := "RFC3339"
	timeParsed, err := time.Parse(time.RFC3339, timestr)
	if err != nil {
		// 如果解析失败，则尝试使用指定的格式解析时间
		timeType = "LAYOUT_DATE_TIME"
		timeParsed, err = time.Parse(LAYOUT_DATE_TIME, timestr)
		if err != nil {
			// 如果两种格式都无法解析，返回错误
			logErr.Println(err)
			now := time.Now()
			timeParsed = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
		}
	}
	return timeParsed, timeType
}

// 将时间字符串转换成LAYOUT_DATE_TIME格式
func ConvertTimestrFormat(inputTime string) string {
	// 尝试使用 RFC3339 格式解析时间
	timeParsed, err := time.Parse(time.RFC3339, inputTime)
	if err != nil {
		// 如果解析失败，则尝试使用指定的格式解析时间
		timeParsed, err = time.Parse(LAYOUT_DATE_TIME, inputTime)
		if err != nil {
			// 如果两种格式都无法解析，返回错误
			return ""
		}
	}

	// 格式化为指定格式
	formattedTime := timeParsed.Format(LAYOUT_DATE_TIME)

	return formattedTime
}

// DatestrToDate 日期字符串转日期
func DatestrToDate(dateStr string) time.Time {
	if date, err := time.Parse(LAYOUT_DATE, dateStr); err != nil {
		logErr.Println(err)
		now := time.Now()
		today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
		return today
	} else {
		return date
	}
}

// GetNextDatestr 获取指定日期后一天
func GetNextDatestr(dateStr string) string {
	if date, err := time.Parse(LAYOUT_DATE, dateStr); err != nil {
		logErr.Println("Error:", err)
		return dateStr
	} else {
		nextDay := date.AddDate(0, 0, 1)
		return nextDay.Format(LAYOUT_DATE)
	}
}

// GetDatestrsBetween 获取日期数组
func GetDatestrsBetween(start, end string) []string {
	startTime, err := time.Parse(LAYOUT_DATE, start)
	if err != nil {
		logErr.Println(err)
		return nil
	}
	endTime, err := time.Parse(LAYOUT_DATE, end)
	if err != nil {
		logErr.Println(err)
		return nil
	}
	var dates []string
	for currTime := startTime; currTime.Before(endTime) || currTime.Equal(endTime); currTime = currTime.AddDate(0, 0, 1) {
		dates = append(dates, currTime.Format(LAYOUT_DATE))
	}
	return dates
}

// FormatDate 按照期望日期格式进行格式化
func FormatDate(dateStr string, format string) string {
	if date, err := time.Parse(LAYOUT_DATE, dateStr); err != nil {
		return dateStr
	} else {
		return date.Format(format)
	}
}

// GetTimePoints 获取时间点
//
// 获取早八点到晚八点的时间，共12个小时 145个数据
func GetTimePoints() []string {

	now := time.Now()
	remainder := (now.Minute()*60 + now.Second()) % 300         //距离上一个整五分的秒数
	endTime := now.Add(time.Duration(-remainder) * time.Second) //取距离最新的整五分时间点
	startTime := endTime.Add(-24*time.Hour + 5*time.Minute)

	// 循环遍历每5分钟的时间点，并添加到数组中
	var timePoints []string
	for t := startTime; t.Before(endTime) || t.Equal(endTime); t = t.Add(5 * time.Minute) {
		hour := t.Hour()
		minute := t.Minute()
		if hour < 8 || hour > 20 || (hour == 20 && minute != 0) {
			continue
		}
		timePoints = append(timePoints, t.Format(LAYOUT_TIME_SIMPLE))
	}
	return timePoints
}

func IntToTimeSimple(stamp int64) string {
	t := time.Unix(stamp, 0)
	return t.Format(LAYOUT_TIME_SIMPLE)
}

func IntToDateTime(stamp int64) string {
	t := time.Unix(stamp, 0)
	return t.Format(LAYOUT_DATE_TIME)
}
